#ifndef __LOG_H_
#define __LOG_H_

#include <stdint.h>
#include <stdarg.h>

#ifdef __cplusplus
extern "C" {
#endif

/* 配置接口 */
#define CFG_LOG_COLOR											1
#define CFG_LOG_LOCAL_LEVEL 							LOG_VERBOSE
#define LOG_OUT(format,...) 							printf(format,##__VA_ARGS__)

typedef enum 
{
	LOG_NONE, 						/*!< 无日志输出 */
	LOG_ERROR, 						/*!< 严重错误，软件模块无法自行恢复 */
	LOG_WARN, 						/*!< 已采取恢复措施的错误条件 */
	LOG_INFO, 						/*!< 描述正常事件流的信息消息 */
	LOG_DEBUG, 						/*!< 正常使用不需要的其他信息（值，指针，大小等）。 */
	LOG_VERBOSE 					/*!< 较大的调试信息块或频繁的消息可能会淹没输出 */
}log_level_t;


#ifndef CFG_LOG_LOCAL_LEVEL
	#define CFG_LOG_LOCAL_LEVEL					LOG_INFO
#endif


#if CFG_LOG_COLOR
	#define LOG_COLOR_BLACK 					"30"
	#define LOG_COLOR_RED 						"31"
	#define LOG_COLOR_GREEN 					"32"
	#define LOG_COLOR_BROWN 					"33"
	#define LOG_COLOR_BLUE 						"34"
	#define LOG_COLOR_PURPLE 					"35"
	#define LOG_COLOR_CYAN 						"36"
	#define LOG_COLOR(COLOR) 					"\033[0;" COLOR "m"
	#define LOG_BOLD(COLOR) 					"\033[1;" COLOR "m"
	#define LOG_RESET_COLOR 					"\033[0m"

	#define LOG_COLOR_E 						LOG_COLOR(LOG_COLOR_RED)
	#define LOG_COLOR_W 						LOG_COLOR(LOG_COLOR_BROWN)
	#define LOG_COLOR_I 						LOG_COLOR(LOG_COLOR_GREEN)
	#define LOG_COLOR_D 						LOG_COLOR(LOG_COLOR_BLUE)
	#define LOG_COLOR_V 						LOG_COLOR(LOG_COLOR_BLACK)
#else
	#define LOG_COLOR_E
	#define LOG_COLOR_W
	#define LOG_COLOR_I
	#define LOG_COLOR_D
	#define LOG_COLOR_V
	#define LOG_RESET_COLOR 
#endif


#define LOG_FORMAT(letter, format) 					LOG_COLOR_ ##letter #letter "(%d)[%s]: " format LOG_RESET_COLOR "\r\n"
#define EARLY_LOGE(tag, format, ... ) 			LOG_EARLY_IMPL(tag, format, LOG_ERROR, E, ##__VA_ARGS__)
#define EARLY_LOGW(tag, format, ... ) 			LOG_EARLY_IMPL(tag, format, LOG_WARN, W, ##__VA_ARGS__)
#define EARLY_LOGI(tag, format, ... ) 			LOG_EARLY_IMPL(tag, format, LOG_INFO, I, ##__VA_ARGS__)
#define EARLY_LOGD(tag, format, ... ) 			LOG_EARLY_IMPL(tag, format, LOG_DEBUG, D, ##__VA_ARGS__)
#define EARLY_LOGV(tag, format, ... ) 			LOG_EARLY_IMPL(tag, format, LOG_VERBOSE, V, ##__VA_ARGS__)

#define LOG_EARLY_IMPL(tag, format, log_level, log_tag_letter, ...) do { \
if (CFG_LOG_LOCAL_LEVEL >= log_level) { \
LOG_OUT(LOG_FORMAT(log_tag_letter, format), LOG_TIMETAMP ,tag, ##__VA_ARGS__); \
}} while(0)

#define HEX_FORMAT_HEARDER(letter,info) LOG_COLOR_ ##letter #letter "(%d)[%s]: " info
#define HEX_FORMAT_END LOG_RESET_COLOR "\r\n"
#define HEXDUMP(P,L) do { \
uint16_t _log_n=0;\
for( _log_n=0;_log_n<L;_log_n++){ \
LOG_OUT("%02X ",P[_log_n]);\
}\
}while(0)
#define LOG_HEX(tag,info,buf,len,log_level,log_tag_letter) do{ \
if(CFG_LOG_LOCAL_LEVEL>log_level){\
LOG_OUT(HEX_FORMAT_HEARDER(log_tag_letter,info),LOG_TIMETAMP,tag);\
HEXDUMP(buf,len);\
LOG_OUT(HEX_FORMAT_END);\
}\
}while(0)



/* 对外接口函数 */

//error
#define log_e(tag, format, ... ) 					EARLY_LOGE(tag, format, ##__VA_ARGS__)
#define log_hex_e(tag,info,buf,len) 			LOG_HEX(tag,info,buf,len,LOG_ERROR,E)

//warning
#define log_w(tag, format, ... ) 					EARLY_LOGW(tag, format, ##__VA_ARGS__)
#define log_hex_w(tag,info,buf,len) 			LOG_HEX(tag,info,buf,len,LOG_WARN,W)

//info
#define log_i(tag, format, ... ) 					EARLY_LOGI(tag, format, ##__VA_ARGS__)
#define log_hex_i(tag,info,buf,len) 			LOG_HEX(tag,info,buf,len,LOG_INFO,I)

//debug
#define log_d(tag, format, ... ) 					EARLY_LOGD(tag, format, ##__VA_ARGS__)
#define log_hex_d(tag,info,buf,len) 			LOG_HEX(tag,info,buf,len,LOG_DEBUG,D)

//verbose
#define log_v(tag, format, ... ) 					EARLY_LOGV(tag, format, ##__VA_ARGS__)
#define log_hex_v( ag,info,buf,len) 			LOG_HEX(tag,info,buf,len,LOG_VERBOSE,V)


#ifdef __cplusplus
}
#endif

#endif

